package com.newsee.remote.ecommerce.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.newsee.remote.SystemConfig;
import com.newsee.remote.common.bean.JsonResult;
import com.newsee.remote.common.bean.JsonReturn;
import com.newsee.remote.common.database.entity.CommerceColipuSkuDetail;
import com.newsee.remote.common.database.entity.ShMaterial;
import com.newsee.remote.common.database.entity.ShMaterialclass;
import com.newsee.remote.common.database.mapper.CommerceColipuSkuDetailMapper;
import com.newsee.remote.common.database.mapper.ShMaterialMapper;
import com.newsee.remote.common.dto.ecommerce.colipu.CheckUpdateSkuColSys;
import com.newsee.remote.common.enumeration.EcommerceEnum;
import com.newsee.remote.common.enumeration.IsCheckEnum;
import com.newsee.remote.common.enumeration.IsDisableEnum;
import com.newsee.remote.common.utils.tools.CcUtils;
import com.newsee.remote.common.utils.tools.DateUtils;
import com.newsee.remote.common.utils.tools.SapXmlBuildUntil;
import com.newsee.remote.common.utils.webservice.HttpWebserviceExecutor;
import com.newsee.remote.ecommerce.service.IShMaterialPurveyCompanyService;
import com.newsee.remote.ecommerce.service.IShMaterialService;
import com.newsee.remote.ecommerce.service.IShMaterialclassService;
import com.newsee.remote.ecommerce.service.ISystemParamvalueService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 物料表服务实现类
 * </p>
 *
 * @author liangzhichen
 * @since 2019-07-22
 */
@Slf4j
@Service
public class ShMaterialServiceImpl extends ServiceImpl<ShMaterialMapper, ShMaterial> implements IShMaterialService {

    @Autowired
    private SystemConfig systemConfig;

    @Value("${materialUrl}")
    private String materialUrl;

    /**
     * sap请求物资主数据的url
     */
    private final static String MATERIAL_METHOD = "MT_IF1042_MATERIAL_INFO_REQ";

    /**
     * 仓库请求start string
     */
    private final static String XML_START = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:sunac:erp:material_info\">\n";

    /**
     * 科力普供应商编码
     */
    private final static String COLIPU_LIFNR = "1000004173";

    @Resource
    private ShMaterialMapper shMaterialMapper;

    @Resource
    private CommerceColipuSkuDetailMapper commerceColipuSkuDetailMapper;

    private final ISystemParamvalueService iSystemParamvalueService;

    private final IShMaterialclassService iShMaterialclassService;

    private final IShMaterialPurveyCompanyService iShMaterialPurveyCompanyService;

    public ShMaterialServiceImpl(IShMaterialclassService iShMaterialclassService, IShMaterialPurveyCompanyService iShMaterialPurveyCompanyService, ISystemParamvalueService iSystemParamvalueService) {
        this.iShMaterialclassService = iShMaterialclassService;
        this.iShMaterialPurveyCompanyService = iShMaterialPurveyCompanyService;
        this.iSystemParamvalueService = iSystemParamvalueService;
    }

    /**
     * 将中间表的数据同步到物料表中
     *
     * @param records 需要同步的数据
     * @return 新增的科力普商品
     */
    @Override
    public List<CommerceColipuSkuDetail> syncSystem(List<CommerceColipuSkuDetail> records) {
        if (CollectionUtils.isEmpty(records)) {
            return null;
        }

        List<Long> ids = CcUtils.collect(records, CommerceColipuSkuDetail::getMaterialId);
        QueryWrapper<ShMaterial> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("Id", ids).eq("IsDisable", IsDisableEnum.NOT_DISABLE.getCode());
        List<ShMaterial> materials = list(queryWrapper);

        //需要修改的商品sku
        List<ShMaterial> updateList = new LinkedList<>();
        LocalDateTime now = LocalDateTime.now();
        try {
            if (CollectionUtils.isNotEmpty(materials)) {
                //全量的商品sku to Map
                Map<Long, CommerceColipuSkuDetail> skusMap = CcUtils.toMap(records, CommerceColipuSkuDetail::getMaterialId);

                //判断已同步的商品是否需要修改
                materials.forEach(skuExist -> {
                    Long skuId = skuExist.getId();
                    CommerceColipuSkuDetail sku = skusMap.get(skuId);
                    if (null == sku) {
                        //不做删除
                        //skuExist.setIsDisable(IsDisableEnum.IS_DISABLE.getCode());
                        skuExist.setUpdateDate(now);
                        updateList.add(skuExist);
                    } else {
                        //判断是否需要修改
                        CheckUpdateSkuColSys checkUpdateSkuCol = checkUpdate(sku, skuExist);
                        if (checkUpdateSkuCol.getEUpdate()) {
                            skuExist.setOtherMaterialCode(sku.getSkuId());
                            updateList.add(checkUpdateSkuCol.getShMaterial());

                            //判断是否需要修改关联供应商关联价格
                            BigDecimal price = new BigDecimal(sku.getPrice().toString());
                            if (skuExist.getRefPrice().equals(price)) {
                                iShMaterialPurveyCompanyService.updateRelate(checkUpdateSkuCol.getShMaterial().getId(), COLIPU_LIFNR, price);
                            }
                        }
                    }

                    //去除
                    records.remove(sku);
                });
            }

            //最后剩下的新增的
            for (CommerceColipuSkuDetail sku : records) {
                ShMaterial material = new ShMaterial();

                boolean flag = commonSet(material, sku);
                if (!flag) {
                    continue;
                }
                material.setCreateDate(now);
                material.setIsDisable(IsDisableEnum.NOT_DISABLE.getCode());
                material.setIscheck(IsCheckEnum.IS_CHECK.getCode());
                //系统同步
                material.setCreateUserID(11111111L);
                material.setUpdateUserID(11111111L);
                material.setSupplierFlag(EcommerceEnum.E_COLIPU.getCode());
                material.setOtherMaterialCode(sku.getSkuId());

                //保存返回主键
                save(material);
                Long id = material.getId();
                sku.setMaterialId(id);

                //关联供应商
                iShMaterialPurveyCompanyService.saveRelate(material, COLIPU_LIFNR);
            }

            if (CollectionUtils.isNotEmpty(updateList)) {
                updateList.forEach(this::updateById);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("中间表的数据同步到物料表中出错:" + e.getMessage());
        }
        return records;
    }

    @Override
    public JsonResult pushMaterial(String startTime, String endTime) {
        log.info("推送增量物资...");
        //查询某时间段内的的增量数据（默认前一天的增量数据）
        List<ShMaterial> materials = getNeedUpdateMaterial(startTime, endTime);
        if (CollectionUtils.isEmpty(materials)) {
            log.info("当前时间段或前一天没有增量物资数据...");
            return JsonReturn.succ("当前时间段或前一天没有增量物资数据");
        }

        int times = materials.size() / 1000;
        log.info("增量物资数据共：" + materials.size() + "条，需推送" + times + "次");
        for (int i = 0; i <= times; i++) {
            List<ShMaterial> materialsPost;
            if (i == times) {
                materialsPost = materials.subList(i * 1000, materials.size());
            } else {
                materialsPost = materials.subList(i * 1000, (i + 1) * 1000);
            }

            //请求业务体
            String message = getMessage(materialsPost);
            //组装xml请求sap
            String request = SapXmlBuildUntil.makeXml(XML_START, MATERIAL_METHOD, systemConfig.getSapReqTarSys(), message);
            //将&替换成"";
            String requestNew = request.replace("＆", "");
            String requestNew1 = requestNew.replace("M&G", "MG");
            String response = HttpWebserviceExecutor.doHttpMethodSap(materialUrl, requestNew1, systemConfig.getSapAccount(), systemConfig.getSapPassword());
            log.info("推送增量物资成功：url:" + materialUrl + "第" + i + "次！");
        }

        return JsonReturn.succ();
    }

    @Override
    public JsonResult syncSkuId() {
        List<ShMaterial> materials = list(new QueryWrapper<ShMaterial>().like("Remark", "科力普"));
        for (ShMaterial material : materials) {
            CommerceColipuSkuDetail skuDetail = commerceColipuSkuDetailMapper.selectOne(new QueryWrapper<CommerceColipuSkuDetail>().eq("MaterialId", material.getId()));
            if (null != skuDetail) {
                material.setOtherMaterialCode(skuDetail.getSkuId());
                updateById(material);
            }
        }
        return JsonReturn.succ();
    }

    /**
     * 封装请求体
     *
     * @param materials 某时间段内的的增量数据
     * @return 请求体
     */
    private String getMessage(List<ShMaterial> materials) {
        StringBuilder message = new StringBuilder();
        message.append("<MESSAGE>\n");
        for (ShMaterial material : materials) {
            message.append("<REQ_ITEM>\n");

            message.append("<MaterialCode>");
            if (StringUtils.isNotBlank(material.getMaterialCode())) {
                message.append(material.getMaterialCode());
            }
            message.append("</MaterialCode>\n");

            message.append("<MaterialName>");
            if (StringUtils.isNotBlank(material.getMaterialName())) {
                message.append(material.getMaterialName());
            }
            message.append("</MaterialName>\n");

            message.append("<Code>");
            if (null != material.getMaterialClassID()) {
                ShMaterialclass materialClass = iShMaterialclassService.getById(material.getMaterialClassID());
                if (null != materialClass) {
                    message.append(materialClass.getCode());
                }
            }
            message.append("</Code>\n");

            message.append("<MATERIAL_BRAND>");
            if (StringUtils.isNotBlank(material.getMaterialName())) {
                message.append(material.getBrand());
            }
            message.append("</MATERIAL_BRAND>\n");

            message.append("<SPECS_MODEL>");
            if (StringUtils.isNotBlank(material.getMaterialName())) {
                message.append(material.getSpec());
            }
            message.append("</SPECS_MODEL>\n");

            message.append("<MEASURE_UNIT>");
            if (StringUtils.isNotBlank(material.getMaterialName())) {
                message.append(iSystemParamvalueService.getUnitName(material.getUnit()));
            }
            message.append("</MEASURE_UNIT>\n");

            message.append("</REQ_ITEM>\n");
        }
        message.append("</MESSAGE>\n");
        return message.toString();
    }

    /**
     * 查询某时间段内的的增量数据（默认前一天的增量数据）
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 时间段内的增量数据
     */
    private List<ShMaterial> getNeedUpdateMaterial(String startTime, String endTime) {
        //没传时间默认取前一天增量的数据
        if (StringUtils.isBlank(startTime) && StringUtils.isBlank(endTime)) {
            Date date = new Date();
            Calendar c = Calendar.getInstance();
            c.add(Calendar.DATE, -1);
            Date yesterday = c.getTime();
            startTime = DateUtils.format(yesterday, "yyyy-MM-dd HH:mm:ss.sss");
            c.setTime(date);
            endTime = DateUtils.format(date, "yyyy-MM-dd HH:mm:ss.sss");
        }

        QueryWrapper<ShMaterial> queryWrapper = new QueryWrapper<>();
        queryWrapper.between("CreateDate", startTime, endTime)
                .or()
                .between("UpdateDate", startTime, endTime);
        return list(queryWrapper);
    }

    /**
     * 数据组装,需要对比的字段
     *
     * @param material 对象
     * @return 是否执行
     */
    private boolean commonSet(ShMaterial material, CommerceColipuSkuDetail sku) {
        String date = DateUtils.format(new Date(), DateUtils.DATE_PATTERN_YMD);

        ShMaterialclass materialClass = iShMaterialclassService.getIdByCode(sku.getCategoryId());
        if (null == materialClass) {
            log.error(sku.getSkuId() + sku.getName() + "缺少该物资对应的物资分类！");
            return false;
        }
        Long materialClassId = materialClass.getId();
        material.setMaterialClassID(materialClassId);

        //生成物资编码
        String code = generatorCode(materialClass.getCode(), materialClassId);
        if (null == code) {
            return false;
        }
        material.setMaterialCode(code);

        //物料名称
        material.setMaterialName(sku.getName());
        //规格型号
        material.setSpec(sku.getModel());

        //关联单位
        material.setUnit(iSystemParamvalueService.getUnit(sku.getUnit()));
        //标准价
        material.setRefPrice(new BigDecimal(sku.getPrice().toString()));
        material.setRemark("科力普系统导入" + date);
        material.setMaterialBarCode(sku.getUpc());
        material.setBrand(sku.getBrandName());
        //图片url
        material.setFileURL(sku.getImagePath());
        return true;
    }

    /**
     * @param code            3级物料分类代码
     * @param materialClassId 3级分类编码，分类表的主键
     * @return 生成的物料编码
     */
    private String generatorCode(String code, Long materialClassId) {
        //该3级物料分类代码下最大的物资
        String maxCode = shMaterialMapper.getMaxByMaterialClassID(materialClassId);
        if (null == maxCode) {
            maxCode = code + "000001";
        } else {
            try {
                String lastStr = maxCode.substring(maxCode.length() - 6);
                int i = Integer.parseInt(lastStr) + 1;
                String newLast = String.format("%06d", i);
                maxCode = code + newLast;
            } catch (Exception e) {
                e.printStackTrace();
                log.error("物料编码生成有误：物料分类编码：" + code);
                return null;
            }
        }
        return maxCode;
    }

    /**
     * 校验是否需要修改
     *
     * @param sku      最新的sku
     * @param skuExist 已存在物料表中的sku
     * @return 校验结果
     */
    private CheckUpdateSkuColSys checkUpdate(CommerceColipuSkuDetail sku, ShMaterial skuExist) {
        CheckUpdateSkuColSys result = new CheckUpdateSkuColSys();

        boolean eUpdate = true;
        ShMaterial shMaterialNew = new ShMaterial();
        BeanUtils.copyProperties(skuExist, shMaterialNew);

        ShMaterialclass materialClass = iShMaterialclassService.getIdByCode(sku.getCategoryId());
        if (null == materialClass) {
            log.error("SkuID:" + sku.getSkuId() + "; 商品:" + sku.getName() + "; 缺少该物资对应的物资分类！");
            eUpdate = false;
        } else {
            Long materialClassId = materialClass.getId();
            shMaterialNew.setMaterialClassID(materialClassId);

            //物料名称
            shMaterialNew.setMaterialName(sku.getName());
            //规格型号
            shMaterialNew.setSpec(sku.getModel());
            //单位
            //shMaterialNew.setUnit(sku.getUnit());
            //标准价
            shMaterialNew.setRefPrice(new BigDecimal(sku.getPrice().toString()));
            shMaterialNew.setMaterialBarCode(sku.getUpc());
            shMaterialNew.setBrand(sku.getBrandName());
            //图片url
            shMaterialNew.setFileURL(sku.getImagePath());
        }

        if (shMaterialNew.equals(skuExist)) {
            eUpdate = false;
        }

        result.setEUpdate(eUpdate);
        result.setShMaterial(shMaterialNew);
        return result;
    }

    public static void main(String[] args) {
        String s = "晨光 MG 12色筒装牛皮纸彩色铅笔 AWP34308 M&G  12支/筒";
        String requestNew = s.replace("&", "");
        System.out.println(requestNew);
    }
}
